AWS Systems Manager Session Managerの利用状況をAmazon Athenaで調べる
はじめに
AWS Systems Manager Session Managerを利用すると、SSH/RDP を使わずに、Amazon EC2 インスタンスを管理できます。
運用の一環として
- Session Manager の利用頻度
- 利用者、対象インスタンスのアクセスコントロール
などを確認したいことがあります。
そのような目的のために、Amazon Athena から AWS CloudTrail に SQL を投げて調査する方法をユースケース別に紹介します。
前提
AWS 操作の証跡を残す AWS CloudTrail を有効にしてください。
また、CloudTrailが取得したログをAthenaで分析できるように、テーブルを作成してください。 テーブルの作成方法は、以下を参照ください。
- AWS CloudTrail ログのクエリ - Amazon Athena - Amazon.com
- [新機能]ワンクリックでAmazon AthenaのAWS CloudTrail用テーブルが作成できるようになりました | DevelopersIO
AWS Systems Manager Session Manager の CloudTrail ログについて
API の種類
AWS Systems Manager Session Manager に関する API は以下があります。
- StartSession - セッションを開始する
- TerminateSession - セッションを終了する
- ResumeSession - 接続されたセッションに再接続する
調査では、これら API を利用します。
Systems Manager Session Manager のログファイルエントリ
StartSession
の場合、次のような CloudTrail ログエントリが作成されます。
{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AAA:jane.doe", "arn": "arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe", "accountId": "123456789012", "accessKeyId": "BBB", "sessionContext": { "attributes": { "mfaAuthenticated": "true", "creationDate": "2019-05-03T14:56:17Z" }, "sessionIssuer": { "type": "Role", "principalId": "CCC", "arn": "arn:aws:iam::123456789012:role/jane.doe", "accountId": "123456789012", "userName": "jane.doe" } } }, "eventTime": "2019-05-03T15:41:58Z", "eventSource": "ssm.amazonaws.com", "eventName": "StartSession", "awsRegion": "eu-central-1", "sourceIPAddress": "1.2.3.4", "userAgent": "aws-internal/3 aws-sdk-java/1.11.534 Linux/4.9.137-0.1.ac.218.74.329.metal1.x86_64 OpenJDK_64-Bit_Server_VM/25.202-b08 java/1.8.0_202 vendor/Oracle_Corporation", "requestParameters": { "target": "i-1234" }, "responseElements": { "sessionId": "jane.doe-0cebe29e113af220c", "tokenValue": "Value hidden due to security reasons.", "streamUrl": "Value hidden due to security reasons." }, "requestID": "ca99926a-...", "eventID": "f832760f-...", "resources": [ { "ARN": "arn:aws:ec2:eu-central-1:123456789012:instance/i-1234", "accountId": "123456789012" } ], "eventType": "AwsApiCall", "recipientAccountId": "123456789012" }
このログエントリから以下の情報がわかります。
- いつ(
eventTime
) - 誰が(
userIdentity.arn
) - どこから(
sourceIPAddress
) - どのインスタンスに(
resources
,requestParameters
) - 何をしたのか(
eventName
)
ユースケース別SQL例
ここからはユースケース別にSQLを紹介します。
API 呼び出し一覧を取得
セッションマネージャー系 API の利用履歴を出力します。
SELECT eventtime, eventname , element_at(resources, 1).arn resource_target, useridentity.arn, sourceipaddress FROM "default"."cloudtrail_logs_table_name" WHERE eventsource = 'ssm.amazonaws.com' AND eventname IN ('StartSession', 'TerminateSession', 'ResumeSession') AND eventtime BETWEEN '2019-04-01T00:00:00Z' AND '2019-05-01T00:00:00Z' ORDER BY eventtime;
出力例
"eventtime","eventname","resource_target","arn","sourceipaddress" "2019-04-03T19:27:31Z","StartSession","arn:aws:ec2:eu-central-1:123456789012:instance/i-1234","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","1.2.3.4" "2019-04-06T08:46:42Z","StartSession","arn:aws:ec2:eu-central-1:123456789012:instance/i-9876","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","1.2.3.4" "2019-04-20T13:03:42Z","TerminateSession","arn:aws:ssm:eu-central-1:123456789012:session/jane.doe-05864affb98807843","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","2.3.4.5"
SQL メモ
resources
は struct の array です。
element_at(resources, 1)
で array の1つ目の要素を抽出し、struct の 変数 arn
には .arn
でアクセスしています。
EC2のインスタンスIDだけがわかれば十分な場合、string 型の requestparameters
を利用し、 json_extract(requestparameters, '$.target')
としてください。
EC2インスタンスとユーザーのペア一覧を取得
Session Manager 利用なインスタンスを制限していたり、本番・開発といった環境によって、Session Manager 可能なユーザーを制限していることがあります。
期待通りにアクセスコントロールできていることを確認するために、 EC2 インスタンスとユーザーのペアを出力します。
SELECT element_at(resources, 1).arn resource_target, useridentity.arn, count(*) cnt FROM "default"."cloudtrail_logs_table_name" WHERE eventsource = 'ssm.amazonaws.com' AND eventname IN ('StartSession', 'TerminateSession', 'ResumeSession') AND eventtime BETWEEN '2019-04-01T00:00:00Z' AND '2019-04-15T00:00:00Z' GROUP BY 1, 2
出力例
"resource_target","arn","cnt" "arn:aws:ec2:eu-central-1:123456789012:instance/i-1234","arn:aws:sts::123456789012:assumed-role/jane.doe/jane.doe","2" "arn:aws:ec2:eu-central-1:123456789012:instance/i-1234","arn:aws:iam::123456789012:assumed-role/john.smith/john.smith","1"
日別の利用頻度を取得
セッションマネージャー系 API の日別の利用数を出力します。
SELECT date_trunc('day', from_iso8601_timestamp(eventtime)) eventtime, count(*) cnt FROM "default"."cloudtrail_logs_table_name" WHERE eventsource = 'ssm.amazonaws.com' AND eventname IN ('StartSession', 'TerminateSession', 'ResumeSession') AND eventtime BETWEEN '2019-04-01T00:00:00Z' AND '2019-04-15T00:00:00Z' GROUP BY 1 ORDER BY 1
出力例
"eventtime","cnt" "2019-04-03 00:00:00.000 UTC","1" "2019-04-06 00:00:00.000 UTC","4" "2019-04-11 00:00:00.000 UTC","2"
SQL メモ
eventime
は string 型のため from_iso8601_timestamp(string)
関数で timestamp 型に変換しています。
さらに、date_trunc(unit, x)
関数により、指定した unit に切り捨てています。
SELECT '2019-05-04T15:41:58Z' ,from_iso8601_timestamp( '2019-05-04T15:41:58Z') ,date_trunc('day', from_iso8601_timestamp( '2019-05-04T15:41:58Z')) -- SELECT 結果 2019-05-04T15:41:58Z, 2019-05-04 15:41:58.000 UTC, 2019-05-04 00:00:00.000 UTC
date_trunc
関数の unit を hour
, month
などにかえることで、集約の粒度を変更できます。
まとめ
AWS Systems Manager Session Manager の利用状況を調査する際のクエリパターンをまとめました。
Session Manager の運用において、リアルタイム通知とは別に、利用状況や正しくアクセスコントロールされていることを確認したい場合、今回の様なアプローチがおすすめです。
それでは。